package net.nyancofc.piconnow.util;

import java.util.concurrent.CountDownLatch;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;

public class InvokeKnock implements Runnable{
	private InvokeKnock(){}
	private Runnable mCallback;
	private CountDownLatch mCount;

	@Override public void run(){
		try{ mCallback.run(); }catch(Throwable e){ Log.e("InvokeKnock","error in callback",e); }
		mCount.countDown();
	}

	// スレッドのHandlerにcallbackをpostした後、その処理が終わるまで待つ
	public static void call(Handler h,Runnable callback){
		// 呼び出し元と呼び出し先が同じスレッドならキューを通さずに直接実行する
		if( Looper.myLooper() == h.getLooper() ){
			try{ callback.run(); }catch(Throwable e){ Log.e("InvokeKnock","error in callback.",e); }
			return;
		}
		// countDown()と組み合わせたRunnableをHandlerにポスト
		InvokeKnock iw = new InvokeKnock();
		iw.mCallback = callback;
		iw.mCount    = new CountDownLatch(1);
		h.post(iw);
		// 処理されるのを待つ
		try{ iw.mCount.await(); }catch(InterruptedException e){
			Log.d("InvokeKnock","calling thread is interrupted while waiting.");
			Thread.currentThread().interrupt(); // 再送出
		}
	}
};

